package com.qujia.station.service.impl;

import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.qujia.common.core.domain.entity.SysUser;
import com.qujia.common.core.redis.RedisCache;
import com.qujia.common.exception.CustomException;
import com.qujia.common.utils.SecurityUtils;
import com.qujia.station.domain.Station;
import com.qujia.station.domain.StationOillGun;
import com.qujia.station.domain.WxMessageTemplate;
import com.qujia.station.domain.dto.StationOilGunDto;
import com.qujia.station.domain.form.StationOillGunPriceForm;
import com.qujia.station.mapper.StationOillGunMapper;
import com.qujia.station.service.IStationOillGunService;
import com.qujia.station.service.IStationService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

/**
 * 油站信息Service业务层处理
 *
 * @author qujia
 * @date 2020-12-08
 */
@Service
@Slf4j
public class StationOillGunServiceImpl implements IStationOillGunService
{
    @Autowired
    private StationOillGunMapper stationOillGunMapper;

    @Autowired
    private IStationOillGunService stationOillGunService;

    @Autowired
    private IStationService stationService;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    public RedisTemplate redisTemplate;

    ThreadPoolExecutor threadPoolExecutor = ThreadUtil.newExecutor(10, 20);

    /**
     * 查询油枪信息
     *
     * @param gunId 油枪信息
     * @return 油品信息
     */
    public StationOillGun selectStationOillGunById(Long gunId){
        return stationOillGunMapper.selectStationOillGunById(gunId);
    }

    /**
     * 查询油枪信息列表
     *
     * @param stationOillGun 油枪信息
     * @return 油枪信息集合
     */
    public List<StationOillGun> selectStationOillGunList(StationOillGun stationOillGun){
        List<StationOillGun> stationOillGunList = stationOillGunMapper.selectStationOillGunList(stationOillGun);
        for (StationOillGun oillGun : stationOillGunList) {
            if(Objects.nonNull(oillGun) && Objects.isNull(oillGun.getPreEffectivePrice())){
                oillGun.setPreEffectivePrice(oillGun.getOilStationPrice());
            }
        }
        return stationOillGunList;
    }

    /**
     * 新增油枪信息
     *
     * @param stationOillGun 油枪信息
     * @return 结果
     */
    public int insertStationOillGun(StationOillGun stationOillGun){
        return stationOillGunMapper.insertStationOillGun(stationOillGun);
    }

    /**
     * 修改油枪信息
     *
     * @param stationOillGun 油枪信息
     * @return 结果
     */
    @CacheEvict(value = { "EnterpriseServiceImpl_selectStaOilGunList"},
            key="'s_' + #root.args[0].getStationId()",
            condition = "#root.args[0] != null"
    )
    public int updateStationOillGun(StationOillGun stationOillGun){
        // 删除redis中缓存的价格
        if(stationOillGun.getStationId()!=null){
            Iterator<String> it = redisCache.keys ("price:"+ stationOillGun.getStationId()+":*").iterator ();
            while (it.hasNext ()) {
                String key = it.next();
                System.out.println();
                //清空缓存中记录的数据
                redisCache.deleteObject(key);
            }
        }

        stationOillGun.setUpdatedTime(new Date());
        stationOillGunMapper.updateStationOillGuntoTemp(stationOillGun);
        return stationOillGunMapper.updateStationOillGun(stationOillGun);
    }

    @Override
    public int updateStationOillGunTime(StationOillGun stationOillGun) {
        return stationOillGunMapper.updateStationOillGunTime(stationOillGun);
    }

    /**
     * 删除油枪信息
     *
     * @param gunId 油枪信息ID
     * @return 结果
     */
    public int deleteStationOillGunById(Long gunId){
        return stationOillGunMapper.deleteStationOillGunById(gunId);
    }

    /**
     * 批量删除油枪信息
     *
     * @param gunIds 需要删除的数据ID
     * @return 结果
     */
    public int deleteStationOillGunByIds(Long[] gunIds){
        return stationOillGunMapper.deleteStationOillGunByIds(gunIds);
    }

    @Override
    public List<StationOillGun> queryStationOillGunforEffectDate() {
        return stationOillGunMapper.queryStationOillGunforEffectDate();
    }

    @Override
    public int updateStationOillGuntoTemp(StationOillGun stationOillGun) {
        return stationOillGunMapper.updateStationOillGuntoTemp(stationOillGun);
    }

    @Override
    public StationOillGun selectStationOillGunTempById(Long gunId) {
        return stationOillGunMapper.selectStationOillGunTempById(gunId);
    }

    @Override
    public int insertStationOillGunTemp(StationOillGun stationOillGun) {
        return stationOillGunMapper.insertStationOillGunTemp(stationOillGun);
    }

    @Override
    public List<Long> queryStationIdByEnterpriseId(Long enterpriseId) {
        return stationOillGunMapper.queryStationIdByEnterpriseId(enterpriseId);
    }

    @Override
    public void updataEffectData(StationOillGun stationOillGun) {
        stationOillGunMapper.updataEffectData(stationOillGun);
    }

    @Override
    public List<StationOillGun> selectByIdAndEnterpriseId(Long oilId, Long enterpriseId) {
        return stationOillGunMapper.selectByIdAndEnterpriseId(oilId, enterpriseId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateStationOillGunPrice(StationOillGunPriceForm stationOillGunPriceForm) {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        if (ObjectUtils.notEqual(sysUser.getUserLevel(), "1"))
            throw new CustomException("使用油企账号操作！");

        stationOillGunPriceForm.getStationOillGunPriceList().forEach(stationOillGunPrice -> {
            if (ObjectUtils.isEmpty(stationOillGunPrice.getOilId())) throw new CustomException("油品id不能为空！");

            List<StationOillGun> stationOillGunList = stationOillGunMapper.selectByIdAndEnterpriseId(stationOillGunPrice.getOilId(), sysUser.getEnterpriseId());
            stationOillGunList.forEach(stationOillGun -> {
                // 油站价格发生变动进行微信模板推送
                if (ObjectUtils.notEqual(stationOillGun.getOilStationPrice(), stationOillGunPrice.getOilStationPrice())) {
                    // 发送模板消息
                    Map<String, String> params = new HashMap<>();
                    params.put("enterpriseId", String.valueOf(stationOillGun.getEnterpriseId()));
                    params.put("stationName", stationOillGun.getStationName());
                    params.put("oilName", stationOillGun.getOilName());
                    params.put("price", stationOillGunPrice.getOilStationPrice() + "元");
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    params.put("date", ObjectUtils.isNotEmpty(stationOillGunPriceForm.getEffectDate()) ? sdf.format(stationOillGunPriceForm.getEffectDate()) : sdf.format(new Date()));
                    params.put("pushDate", ObjectUtils.isNotEmpty(stationOillGunPriceForm.getPushDate()) ? sdf.format(stationOillGunPriceForm.getPushDate()) : sdf.format(new Date()));
                    log.info("微信模板redis入参：{}", params);
                    redisCache.redisTemplate.opsForList().leftPush(WxMessageTemplate.WX_MESSAGE_TEMPLATE_REDIS_KEY, JSONUtil.toJsonStr(params));
                }

                //更新油站修改时间
                Station updateStation = new Station();
                updateStation.setStationId(stationOillGun.getStationId());
                stationService.updateStation(updateStation);

                StationOillGun newStationOillGun = new StationOillGun();
                newStationOillGun.setGunId(stationOillGun.getGunId());
                newStationOillGun.setUpdatedTime(new Date());

                Date currentTime = new Date();
                Date effectDate = stationOillGunPriceForm.getEffectDate();
                if (ObjectUtils.isEmpty(stationOillGunPriceForm.getEffectDate()) || effectDate.before(currentTime)) {
                    newStationOillGun.setOilOfficialPrice(stationOillGunPrice.getOilOfficialPrice());
                    newStationOillGun.setDiscountPrice(stationOillGunPrice.getDiscountPrice());
                    newStationOillGun.setOilStationPrice(stationOillGunPrice.getOilStationPrice());
                    newStationOillGun.setEffectDate(currentTime);
                } else {
                    newStationOillGun.setEffectDate(effectDate);

                    stationOillGun.setUpdatePriceFlag("N");
                    stationOillGun.setOilStationPrice(stationOillGunPrice.getOilOfficialPrice());
                    stationOillGun.setDiscountPrice(stationOillGunPrice.getDiscountPrice());
                    stationOillGun.setOilStationPrice(stationOillGunPrice.getOilStationPrice());
                    stationOillGun.setEffectDate(effectDate);
                    if(selectStationOillGunTempById(stationOillGun.getGunId())==null){
                        insertStationOillGunTemp(stationOillGun);
                    } else {
                        updateStationOillGuntoTemp(stationOillGun);
                    }
                }
                updateStationOillGun(newStationOillGun);
            });
        });
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void smallProgramUpdateOilGunPrice(StationOillGunPriceForm stationOillGunPriceForm) {
        log.info("小程序调整价格入参：StationId:{}EffectDate:{},PushDate:{}",stationOillGunPriceForm.getStationId(),stationOillGunPriceForm.getEffectDate(),stationOillGunPriceForm.getPushDate());
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        if (sysUser.getUserLevel().equals("1") || sysUser.getUserLevel().equals("2")){
            stationOillGunPriceForm.getStationOillGunPriceList().forEach(stationOillGunPrice -> {
                if (ObjectUtils.isEmpty(stationOillGunPrice.getOilId())) throw new CustomException("油品id不能为空！");

                List<StationOillGun> stationOillGuns = stationOillGunMapper.selectByIdAndStationId(stationOillGunPrice.getOilId(), stationOillGunPriceForm.getStationId());
                stationOillGuns.forEach(stationOillGun -> {
                    // 油站价格发生变动进行微信模板推送
                    if (ObjectUtils.notEqual(stationOillGun.getOilStationPrice(), stationOillGunPrice.getOilStationPrice())) {
                        // 发送模板消息
                        Map<String, String> params = new HashMap<>();
                        params.put("enterpriseId", String.valueOf(stationOillGun.getEnterpriseId()));
                        params.put("stationName", stationOillGun.getStationName());
                        params.put("oilName", stationOillGun.getOilName());
                        params.put("price", stationOillGunPrice.getOilStationPrice() + "元");
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        params.put("date", ObjectUtils.isNotEmpty(stationOillGunPriceForm.getEffectDate()) ? sdf.format(stationOillGunPriceForm.getEffectDate()) : sdf.format(new Date()));
                        params.put("pushDate", ObjectUtils.isNotEmpty(stationOillGunPriceForm.getPushDate()) ? sdf.format(stationOillGunPriceForm.getPushDate()) : null);
                        log.info("微信模板redis入参：{}", params);
                        redisCache.redisTemplate.opsForList().leftPush(WxMessageTemplate.WX_MESSAGE_TEMPLATE_REDIS_KEY, JSONUtil.toJsonStr(params));
                    }

                    //更新油站修改时间
                    Station updateStation = new Station();
                    updateStation.setStationId(stationOillGun.getStationId());
                    stationService.updateStation(updateStation);
// 最后一次修改时间
                    StationOillGun updateTime = new StationOillGun();
                    updateTime.setUpdatedTime(new Date());
                    updateTime.setGunId(stationOillGun.getGunId());
                    stationOillGunService.updateStationOillGun(updateTime);

                    StationOillGun newStationOillGun = new StationOillGun();
                    newStationOillGun.setGunId(stationOillGun.getGunId());
                    newStationOillGun.setUpdatedTime(new Date());

                    Date currentTime = new Date();
                    Date effectDate = stationOillGunPriceForm.getEffectDate();
                    if (ObjectUtils.isEmpty(stationOillGunPriceForm.getEffectDate()) || effectDate.before(currentTime)) {
                        newStationOillGun.setOilOfficialPrice(stationOillGunPrice.getOilOfficialPrice());
                        newStationOillGun.setDiscountPrice(stationOillGunPrice.getDiscountPrice());
                        newStationOillGun.setOilStationPrice(stationOillGunPrice.getOilStationPrice());
                        newStationOillGun.setEffectDate(currentTime);
                    } else {
                        newStationOillGun.setEffectDate(effectDate);

                        stationOillGun.setUpdatePriceFlag("N");
                        stationOillGun.setOilStationPrice(stationOillGunPrice.getOilOfficialPrice());
                        stationOillGun.setDiscountPrice(stationOillGunPrice.getDiscountPrice());
                        stationOillGun.setOilStationPrice(stationOillGunPrice.getOilStationPrice());
                        stationOillGun.setEffectDate(effectDate);
                        if(selectStationOillGunTempById(stationOillGun.getGunId())==null){
                            insertStationOillGunTemp(stationOillGun);
                        } else {
                            updateStationOillGuntoTemp(stationOillGun);
                        }

                        // 小程序预约修改价格
                        List<StationOillGun> stationOillGuntoTemp=null;
                        Boolean hasKey = redisTemplate.hasKey("stationOillGuntoTemp");
                        if(!hasKey){
                            stationOillGuntoTemp = new ArrayList<>();
                        }else{
                            stationOillGuntoTemp = JSONArray.parseArray(redisCache.getCacheObject("stationOillGuntoTemp"),StationOillGun.class);
                        }
                        stationOillGun.setUpdatedTime(null);
                        stationOillGuntoTemp = stationOillGuntoTemp.stream().filter(i -> !i.getGunId().equals(stationOillGun.getGunId())).collect(Collectors.toList());
                        stationOillGuntoTemp.add(stationOillGun);
                        redisCache.setCacheObject("stationOillGuntoTemp", JSON.toJSONString(stationOillGuntoTemp));

                    }
                    updateStationOillGun(newStationOillGun);
                });
            });
        }else {
            throw new CustomException("请使用油企账号或者油站账号！");
        }
    }

    @Override
    public List<StationOilGunDto> selectStaGunInfoByStationId(StationOilGunDto stationOilGunDto) {
        return stationOillGunMapper.selectStaGunInfoByStationId(stationOilGunDto);
    }
}
